#-------------------------------------------------------------------------------
# Name:        converter.py
# Purpose:     Classes to convert input files to the SlideSpeech output
#
# Authors:     Glenn Ramsey <glenn.ramsey@slidespeech.com>
#              John Graves <john.graves@slidespeech.com>
#
# Copyright:   (c) Slidespeech Ltd 2012
# Licence:     MIT license
#-------------------------------------------------------------------------------

import codecs, os, shutil, sys
from collections import namedtuple
from tempfile import mktemp
from jinja2 import Environment, FileSystemLoader
import gettext
import jinja2.ext
import webbrowser

from converter_error import ConverterError

# placeholder translation function
def _():
    lambda x:x

class Converter:
    """Base class for presentation converters"""
    # Public interface
    def __init__(self, previous):
        self._previous = previous
        self._debug = True
        if self._previous is None:
            self._script = {}
            # the top level is a Sequence
            seq = []
            self._script['S'] = seq

    def convert(self):
        """Compose a chain of converters and then call the _convertImpl function of
           each one in order"""
        self._chain = []
        o = self
        while not o.previous() is None:
            self._chain.insert(0,o)
            o = o.previous()
        self._chain.insert(0,o)

        for o in self._chain:
            o._convertImpl()

        self.cleanUp()

    def cleanUp(self):
        """Call the _cleanUpImpl function of each object in the chain in reverse order"""
        self._chain.reverse()

        for o in self._chain:
            o._cleanUpImpl()

        if not self._debug:
            # remove the temporary dir
            tmp = self.tempDir(False)
            try:
                if not tmp is None:
                    shutil.rmtree(tmp)
            except IOError as e:
                ex = ConverterError("Could not remove temporary directory", e)
                raise ex

    def previous(self):
        return self._previous

    def _convertImpl(self):
        """Derived classes must override this"""
        raise NotImplementedError()

    def _cleanUpImpl(self):
        """Derived classes should override this if they have clean up to do"""
        pass

    def script(self):
        if self._previous is None:
            return self._script
        else:
            return self._previous.script()

    def slideList(self):
        # ideally we should have an abstraction for slides, in case they are not PNG images
        if not self._previous is None:
            return self._previous.slideList()
        return None

    def tempDir(self, create=True, parent=None):
        #print self.__class__.__name__, self.tempDir.__name__

        # Search the decorator chain for a tempDir, if one doesn't exist
        # then create one in this object.

        if hasattr(self, "_tempDir"):
            return self._tempDir
        else:
            foundDir = None
            if not self._previous is None:
                foundDir = self._previous.tempDir(create, self)

            if foundDir:
                return self._previous.tempDir(False)
            elif create and parent is None:
                if self._debug:
                    self._tempDir = os.path.join(os.getcwd(), "tmp")
                else:
                    self._tempDir = mktemp()
                try:
                    os.makedirs(self._tempDir)
                except OSError:
                    # dir already exists, shouldn't happen
                    pass
                return self._tempDir

    # Protected interface
    def _convertPrevious(self):
        if not self._previous is None:
            self._previous.convert()

    def _cleanUpPrevious(self):
        if not self._previous is None:
            self._previous.cleanUp()
        else:
            Converter.cleanUp(self)

